package com.android.baseconfig.common.views.loading.indicators;

import android.animation.ValueAnimator;
import android.graphics.Canvas;
import android.graphics.Paint;

import com.android.baseconfig.common.views.loading.Indicator;

import java.util.ArrayList;

import androidx.interpolator.view.animation.FastOutSlowInInterpolator;

public class DotChaseIndicator extends Indicator {

    public static final float POT1_SCALE_START = 0.4f;
    public static final float POT1_SCALE_END = 0.7f;
    public static final float POT2_SCALE_START = POT1_SCALE_END;
    public static final float POT2_SCALE_END = 1f;
    public static final float POT3_SCALE_START = POT2_SCALE_END;
    public static final float POT3_SCALE_END = POT1_SCALE_END;
    public static final float POT4_SCALE_START = POT1_SCALE_END;
    public static final float POT4_SCALE_END = POT1_SCALE_START;

    public static final int POT1_ALPHA_START = 150;
    public static final int POT1_ALPHA_END = POT1_ALPHA_START;
    public static final int POT2_ALPHA_START = POT1_ALPHA_START;
    public static final int POT2_ALPHA_END = 155;
    public static final int POT3_ALPHA_START = POT2_ALPHA_END;
    public static final int POT3_ALPHA_END = 255;
    public static final int POT4_ALPHA_START = 255;
    public static final int POT4_ALPHA_END = 255;
    float[] translateX = new float[2], translateY = new float[2];
    private float[] scaleFloats = new float[]{POT1_SCALE_START, POT2_SCALE_START, POT3_SCALE_START,
            POT4_SCALE_START,
            };

    int[] alphas = new int[]{POT1_ALPHA_START, POT2_ALPHA_START ,POT3_ALPHA_START,
            POT4_ALPHA_START,
            POT3_ALPHA_START,};
    float circleSpacing = 28;
    float radius = (getWidth() - circleSpacing * 2) / 6;
    float halfWidth = getWidth() / 2f;
    float startX = halfWidth - (radius * 2 + circleSpacing);
    float startY = halfWidth - radius;

    @Override
    public void draw(Canvas canvas, Paint paint) {
        // float circleSpacing = 28;
        // float radius = (getWidth() - circleSpacing * 2) / 6;
        // float x = getWidth() / 2f - (radius * 2 + circleSpacing);
        // float y = getHeight() / 2f;

        // float radius = (getWidth() - circleSpacing * 2) / 6;
        // float startX = getWidth() / 2f - (radius * 2 + circleSpacing);
        // float startY = getWidth() / 2f - radius;
        // Logc.i("radius: " + radius + ", halfWidth: " + halfWidth);

        if (radius <= 0) {
            return;
        }
        // 第一个点：缩放从小到大
        canvas.save();
        canvas.translate(startX, startY);
        canvas.scale(scaleFloats[0], scaleFloats[0]);
        paint.setAlpha(alphas[0]);
        canvas.drawCircle(0, 0, radius, paint);
        canvas.restore();

        // 第二个点：平移从左到右，缩放从小到大，透明从小到大
        if (translateX[0] > 0) {
            canvas.save();
            canvas.translate(translateX[0], startY);
            canvas.scale(scaleFloats[1], scaleFloats[1]);
            paint.setAlpha(alphas[1]);
            canvas.drawCircle(0, 0, radius, paint);
            canvas.restore();
        }

        // 第三个点：平移从左到右，缩放从小到大，透明从小到大
        if (translateX[1] > 0) {
            canvas.save();
            canvas.translate(translateX[1], startY);
            canvas.scale(scaleFloats[2], scaleFloats[2]);
            paint.setAlpha(alphas[2]);
            canvas.drawCircle(0, 0, radius, paint);
            canvas.restore();
        }

        // 第四个点：缩放从大到小
        canvas.save();
        canvas.translate(getWidth() - startX - 2 * radius, startY);
        canvas.scale(scaleFloats[3], scaleFloats[3]);
        paint.setAlpha(alphas[3]);
        canvas.drawCircle(0, 0, radius, paint);
        canvas.restore();
        canvas.save();

        // 第五个点，中间固定，解决第二个点结束后调回第一个点位置的留白
        // int alpha = paint.getAlpha();
        // canvas.save();
        // canvas.translate(halfWidth - radius, startY);
        // canvas.scale(scaleFloats[1], scaleFloats[1]);
        // paint.setAlpha(alphas[4]);
        // canvas.drawCircle(0, 0, radius, paint);
        // canvas.restore();
        // paint.setAlpha(alpha);

        // canvas.save();
        // // float translateX = x + (radius * 2) * i + circleSpacing * i;
        // canvas.translate(halfWidth - radius, startY);
        // canvas.scale(scaleFloats[1], scaleFloats[1]);
        // // paint.setAlpha(alphas[i]);
        // canvas.drawCircle(0, 0, radius, paint);
        // canvas.restore();
    }

    @Override
    public ArrayList<ValueAnimator> onCreateAnimators() {
        radius = (getWidth() - circleSpacing * 2) / 6;
        halfWidth = getWidth() / 2f;
        startX = halfWidth - (radius * 2 + circleSpacing);
        startY = halfWidth - radius;

        ArrayList<ValueAnimator> animators = new ArrayList<>();
        int duration = 1000 *3;
        int delay = 250 *3;

        int[] delays = new int[]{0, duration - 10, delay, duration + delay };
        // for (int i = 0; i < 3; i++) {

        // 第一个点缩放
        ValueAnimator scaleAnim1 = ValueAnimator.ofFloat(POT1_SCALE_START, POT1_SCALE_END);
        scaleAnim1.setDuration(duration);
        scaleAnim1.setRepeatCount(-1);
        scaleAnim1.setStartDelay(delays[0]);
        addUpdateListener(scaleAnim1, new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                scaleFloats[0] = (float) animation.getAnimatedValue();
                postInvalidate();
            }
        });
        animators.add(scaleAnim1);

        // 第二个点缩放
        ValueAnimator scaleAnim2 = ValueAnimator.ofFloat(POT2_SCALE_START, POT2_SCALE_END);
        scaleAnim2.setDuration(duration);
        scaleAnim2.setRepeatCount(-1);
        scaleAnim2.setStartDelay(delays[1]);
        addUpdateListener(scaleAnim2, new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                scaleFloats[1] = (float) animation.getAnimatedValue();
                postInvalidate();
            }
        });
        animators.add(scaleAnim2);

        // 第二个点：透明从小到大
        ValueAnimator alphaAnim2 = ValueAnimator.ofInt(POT2_ALPHA_START, POT2_ALPHA_END);
        // ValueAnimator alphaAnim2 = ValueAnimator.ofInt(POT2_ALPHA_START, POT1_ALPHA_END,
        //         POT2_ALPHA_END, POT2_ALPHA_END, POT2_ALPHA_END, POT2_ALPHA_END);
        alphaAnim2.setDuration(duration);
        alphaAnim2.setRepeatCount(-1);
        alphaAnim2.setStartDelay(delays[1]);
        addUpdateListener(alphaAnim2, new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                alphas[1] = (int) animation.getAnimatedValue();
                postInvalidate();
            }
        });
        animators.add(alphaAnim2);

        // 第三个点缩放
        ValueAnimator scaleAnim3 = ValueAnimator.ofFloat(POT3_SCALE_START, POT3_SCALE_END);
        scaleAnim3.setDuration(duration);
        scaleAnim3.setRepeatCount(-1);
        scaleAnim3.setStartDelay(delays[2]);
        addUpdateListener(scaleAnim3, new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                scaleFloats[2] = (float) animation.getAnimatedValue();
                postInvalidate();
            }
        });
        animators.add(scaleAnim3);

        // 第三个点：透明从小到大
        ValueAnimator alphaAnim3 = ValueAnimator.ofInt(POT3_ALPHA_START, POT3_ALPHA_END);
        alphaAnim3.setDuration(duration);
        alphaAnim3.setRepeatCount(-1);
        alphaAnim3.setStartDelay(delays[2]);
        addUpdateListener(alphaAnim3, new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                alphas[2] = (int) animation.getAnimatedValue();
                postInvalidate();
            }
        });
        animators.add(alphaAnim3);

        // 第四个点缩放
        ValueAnimator scaleAnim4 = ValueAnimator.ofFloat(POT4_SCALE_START, POT4_SCALE_END);
        scaleAnim4.setDuration(duration);
        scaleAnim4.setRepeatCount(-1);
        scaleAnim4.setStartDelay(delays[3]);
        addUpdateListener(scaleAnim4, new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                scaleFloats[3] = (float) animation.getAnimatedValue();
                postInvalidate();
            }
        });
        animators.add(scaleAnim4);

        // 2 3
        // float radius = (getWidth() - circleSpacing * 2) / 6;
        // float startX = halfWidth - (radius * 2 + circleSpacing);
        for (int i = 0; i < 2; i++) {
            final int index = i;
            // ValueAnimator translateXAnim = ValueAnimator.ofFloat(startX, (getWidth() / 2 - 2 * radius)/4 + radius,
            //         (getWidth() / 2 - 2 * radius)/2 + radius, (getWidth() / 2 - 2 * radius) * 3/4 + radius,
            //         getWidth() / 2 - radius);
            ValueAnimator translateXAnim = ValueAnimator.ofFloat(startX, halfWidth - radius);
            if (i == 1) {
                translateXAnim = ValueAnimator.ofFloat(halfWidth - radius, getWidth() - startX - 2 * radius);
            }

            translateXAnim.setDuration(duration);
            translateXAnim.setInterpolator(new FastOutSlowInInterpolator());
            translateXAnim.setStartDelay(delays[1]);
            if (i == 1) {
                translateXAnim.setStartDelay(delays[2]);
            }
            translateXAnim.setRepeatCount(-1);
            addUpdateListener(translateXAnim, new ValueAnimator.AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator animation) {
                    translateX[index] = (float) animation.getAnimatedValue();
                    postInvalidate();
                }
            });
            animators.add(translateXAnim);
        }

        // 第五个点，中间固定，解决第二个点结束后调回第一个点位置的留白
        ValueAnimator alphAnim5 = ValueAnimator.ofInt(255, 255, 0, 0, 0, 0, 0);
        alphAnim5.setDuration(duration);
        alphAnim5.setRepeatCount(-1);
        alphAnim5.setStartDelay(delays[1] + duration - 10);
        addUpdateListener(alphAnim5, new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                alphas[4] = (int) animation.getAnimatedValue();
                postInvalidate();
            }
        });
        animators.add(alphAnim5);

        return animators;
    }


}
